Skip to content

Commit 5b253d6

Browse files
committed
config: keep bailing on unreadable global files
The behaviour for `git config list` is: A. Without `--global`, it should not bail on unreadable/non-existent global config files. B. With `--global`, it should bail when both `$HOME/.gitconfig` and `$XDG_CONFIG_HOME/git/config` are unreadable. It should not bail when one or more of them is readable. The previous patch introduced a regression in scenario B: running `git config list --global` would not fail when both global config files are unreadable. For example, `GIT_CONFIG_GLOBAL=does-not-exist git config list --global` would exit with status code 0. Assuming that `config_source->scope == CONFIG_SCOPE_GLOBAL` iff the `--global` argument is specified, use this to determine whether to bail. When reading only the global scope and both config files are unreadable, then adjust the return code to be non-zero. Note: The logic to determine the exit code does not actually sum the return codes of the underlying operations. Instead, it uses a single decrement operation. If this is undesirable, we can change it to sum the return codes of the underlying operations instead. Lastly, modify the tests to remove the known breakage/regression. The tests for scenario B should now pass. Helped-by: Derrick Stolee <[email protected]> Signed-off-by: Delilah Ashley Wu <[email protected]>
1 parent 639bc7b commit 5b253d6

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

config.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,8 +1498,8 @@ int git_config_system(void)
14981498
}
14991499

15001500
static int do_git_config_sequence(const struct config_options *opts,
1501-
const struct repository *repo,
1502-
config_fn_t fn, void *data)
1501+
const struct repository *repo, config_fn_t fn,
1502+
void *data, enum config_scope scope)
15031503
{
15041504
int ret = 0;
15051505
char *system_config = git_system_config();
@@ -1532,15 +1532,34 @@ static int do_git_config_sequence(const struct config_options *opts,
15321532
NULL);
15331533

15341534
if (!opts->ignore_global) {
1535+
int global_config_success_count = 0;
1536+
int nonzero_ret_on_global_config_error = scope == CONFIG_SCOPE_GLOBAL;
1537+
15351538
git_global_config_paths(&user_config, &xdg_config);
15361539

1537-
if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK))
1538-
ret += git_config_from_file_with_options(fn, xdg_config, data,
1539-
CONFIG_SCOPE_GLOBAL, NULL);
1540+
if (xdg_config &&
1541+
!access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK)) {
1542+
ret += git_config_from_file_with_options(fn, xdg_config,
1543+
data,
1544+
CONFIG_SCOPE_GLOBAL,
1545+
NULL);
1546+
if (!ret)
1547+
global_config_success_count++;
1548+
}
1549+
1550+
if (user_config &&
1551+
!access_or_die(user_config, R_OK, ACCESS_EACCES_OK)) {
1552+
ret += git_config_from_file_with_options(fn, user_config,
1553+
data,
1554+
CONFIG_SCOPE_GLOBAL,
1555+
NULL);
1556+
if (!ret)
1557+
global_config_success_count++;
1558+
}
15401559

1541-
if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK))
1542-
ret += git_config_from_file_with_options(fn, user_config, data,
1543-
CONFIG_SCOPE_GLOBAL, NULL);
1560+
if (nonzero_ret_on_global_config_error &&
1561+
!global_config_success_count)
1562+
--ret;
15441563

15451564
free(xdg_config);
15461565
free(user_config);
@@ -1601,7 +1620,10 @@ int config_with_options(config_fn_t fn, void *data,
16011620
ret = git_config_from_blob_ref(fn, repo, config_source->blob,
16021621
data, config_source->scope);
16031622
} else {
1604-
ret = do_git_config_sequence(opts, repo, fn, data);
1623+
ret = do_git_config_sequence(opts, repo, fn, data,
1624+
config_source ?
1625+
config_source->scope :
1626+
CONFIG_SCOPE_UNKNOWN);
16051627
}
16061628

16071629
if (inc.remote_urls) {

t/t1300-config.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,7 +2372,7 @@ test_expect_success 'list with nonexistent global config' '
23722372
git config ${mode_prefix}list --show-scope
23732373
'
23742374

2375-
test_expect_failure 'list --global with nonexistent global config' '
2375+
test_expect_success 'list --global with nonexistent global config' '
23762376
rm -rf "$HOME"/.gitconfig "$HOME"/.config/git/config &&
23772377
test_must_fail git config ${mode_prefix}list --global --show-scope
23782378
'
@@ -2483,7 +2483,7 @@ test_expect_success 'override global and system config' '
24832483
test_cmp expect output
24842484
'
24852485

2486-
test_expect_failure 'override global and system config with missing file' '
2486+
test_expect_success 'override global and system config with missing file' '
24872487
test_must_fail env GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=/dev/null git config ${mode_prefix}list --global &&
24882488
test_must_fail env GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=does-not-exist git config ${mode_prefix}list --system &&
24892489
GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=does-not-exist git version

0 commit comments

Comments
 (0)