Skip to content

Commit 8fd6c76

Browse files
committed
config: keep bailing on unreadable global files
The expected 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` exits 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: When bailing, the exit code is not determined by sum of the return codes of the underlying operations. Instead, the exit code is modified via a single decrement. 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 will now pass. Helped-by: Derrick Stolee <[email protected]> Signed-off-by: Delilah Ashley Wu <[email protected]>
1 parent f847d00 commit 8fd6c76

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
@@ -1500,8 +1500,8 @@ int git_config_system(void)
15001500
}
15011501

15021502
static int do_git_config_sequence(const struct config_options *opts,
1503-
const struct repository *repo,
1504-
config_fn_t fn, void *data)
1503+
const struct repository *repo, config_fn_t fn,
1504+
void *data, enum config_scope scope)
15051505
{
15061506
int ret = 0;
15071507
char *system_config = git_system_config();
@@ -1534,15 +1534,34 @@ static int do_git_config_sequence(const struct config_options *opts,
15341534
NULL);
15351535

15361536
if (!opts->ignore_global) {
1537+
int global_config_success_count = 0;
1538+
int nonzero_ret_on_global_config_error = scope == CONFIG_SCOPE_GLOBAL;
1539+
15371540
git_global_config_paths(&user_config, &xdg_config);
15381541

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

1543-
if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK))
1544-
ret += git_config_from_file_with_options(fn, user_config, data,
1545-
CONFIG_SCOPE_GLOBAL, NULL);
1562+
if (nonzero_ret_on_global_config_error &&
1563+
!global_config_success_count)
1564+
--ret;
15461565

15471566
free(xdg_config);
15481567
free(user_config);
@@ -1603,7 +1622,10 @@ int config_with_options(config_fn_t fn, void *data,
16031622
ret = git_config_from_blob_ref(fn, repo, config_source->blob,
16041623
data, config_source->scope);
16051624
} else {
1606-
ret = do_git_config_sequence(opts, repo, fn, data);
1625+
ret = do_git_config_sequence(opts, repo, fn, data,
1626+
config_source ?
1627+
config_source->scope :
1628+
CONFIG_SCOPE_UNKNOWN);
16071629
}
16081630

16091631
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)