From: Junio C Hamano <gitster@pobox.com>
To: Delilah Ashley Wu <delilahwu@linux.microsoft.com>
Cc: git@vger.kernel.org, Nils Fahldieck <nils@fahldieck.de>,
Patrick Steinhardt <ps@pks.im>,
Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>,
Delilah Ashley Wu <delilahwu@microsoft.com>,
Derrick Stolee <stolee@gmail.com>,
Ben Knoble <ben.knoble@gmail.com>,
Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: Re: [PATCH v2 2/3] config: let sequence require a successful file
Date: Wed, 26 Aug 2026 11:20:22 -0700 [thread overview]
Message-ID: <xmqqy0dsg2vt.fsf@gitster.g> (raw)
In-Reply-To: <20260823-fix-config-list-global-home-and-xdg-v2-2-b29cc63f017b@microsoft.com> (Delilah Ashley Wu's message of "Sun, 23 Aug 2026 20:28:27 +1000")
Delilah Ashley Wu <delilahwu@linux.microsoft.com> writes:
> From: Delilah Ashley Wu <delilahwu@microsoft.com>
>
> 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.
It is not exactly 'irrelevant' as that is how the user learns what
caused the command to fail, e.g. "fatal: unable to read config file <path>".
What you meant was that you are not interested in the exact message,
you only want to make sure it fails because of the missing file, and
you thought that it is a good way to do so to check the exit code.
> Signed-off-by: Delilah Ashley Wu <delilahwu@microsoft.com>
> ---
> config.c | 57 ++++++++++++++++++++++++++++++++++++++-----------------
> t/t1300-config.sh | 12 ++++++++++++
> 2 files changed, 52 insertions(+), 17 deletions(-)
>
> diff --git a/config.c b/config.c
> index 1bdd702e7a..4c958f46bf 100644
> --- a/config.c
> +++ b/config.c
> @@ -1544,11 +1544,27 @@ int git_config_system(void)
> return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
> }
Perhaps "attempt" -> "try" or something more clever can be used to
make sure we won't have to type so many characters. "try_config()"
should be decriptive enough for the purpose, for example.
File scope static helper functions do not have to be and should not
be named with so many words. Shorter names would also help to keep
your lines under ~70 column limit.
> +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);
>
If we are allowed to use system config, system_config is defined,
and we can read the system config, we try to grab values from it,
and record the fact that we did so successfully.
> git_global_config_paths(&user_config, &xdg_config);
We grab paths to two files, as before.
> 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 xdg config is to be used (note: GIT_CONFIG_GLOBAL environment can
disable the use of it) and xdg file is available, we read and record
just like we saw is done for the system config above.
> 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);
Ditto fo user config.
> 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);
And the local one.
> 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);
And the per-worktree one.
> 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;
If we are asked to ensure that we successfully read at least one
place and we didn't, we assign -1 to ret but we do so ONLY when we
haven't seen any other errors (i.e., existing non-zero ret is
preserved, which may not be -1). OK.
> return ret;
> }
I am not convinced 100% that we need "success_count", either, until
we see how it is used in the later steps. But from the way the
try_config() thing is used, I find it dubious that it now returns
void. It should just keep returning the error code as before, and
the caller should just keep accumulcating as the original code used
to. I.e.,
ret += try_config(fn, frotz_config, data,
CONFIG_SCOPE_FROTZ, NULL,
&success);
next prev parent reply other threads:[~2026-08-26 18:20 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-10 1:14 [PATCH/RFC 0/4] config: read both home and xdg files for --global Delilah Ashley Wu via GitGitGadget
2025-10-10 1:14 ` [PATCH/RFC 1/4] cleanup_path: force forward slashes on Windows Delilah Ashley Wu via GitGitGadget
2025-11-19 17:47 ` Junio C Hamano
2025-10-10 1:14 ` [PATCH/RFC 2/4] config: test home and xdg files in `list --global` Delilah Ashley Wu via GitGitGadget
2025-11-19 18:29 ` Junio C Hamano
2025-10-10 1:14 ` [PATCH/RFC 3/4] config: read global scope via config_sequence Delilah Ashley Wu via GitGitGadget
2025-11-19 18:39 ` Junio C Hamano
2025-10-10 1:14 ` [PATCH/RFC 4/4] config: keep bailing on unreadable global files Delilah Ashley Wu via GitGitGadget
2025-10-10 1:27 ` [PATCH/RFC 0/4] config: read both home and xdg files for --global Kristoffer Haugsbakk
2025-11-22 1:36 ` Delilah Ashley Wu
2026-01-20 20:41 ` Junio C Hamano
2025-11-17 13:29 ` Johannes Schindelin
2025-11-18 0:28 ` Junio C Hamano
2025-11-19 14:44 ` Junio C Hamano
2025-11-22 2:00 ` Delilah Ashley Wu
2026-08-23 10:28 ` [PATCH v2 0/3] " Delilah Ashley Wu
2026-08-23 10:28 ` [PATCH v2 1/3] path: use forward slashes in XDG config on Windows Delilah Ashley Wu
2026-08-26 17:58 ` Junio C Hamano
2026-09-10 4:48 ` Delilah Ashley Wu
2026-08-23 10:28 ` [PATCH v2 2/3] config: let sequence require a successful file Delilah Ashley Wu
2026-08-26 18:20 ` Junio C Hamano [this message]
2026-08-23 10:28 ` [PATCH v2 3/3] config: read global scope via config_sequence Delilah Ashley Wu
2026-08-26 18:38 ` Junio C Hamano
2026-08-23 12:36 ` [PATCH v2 0/3] config: read both home and xdg files for --global Chris Torek
2026-08-24 1:32 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqy0dsg2vt.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=ben.knoble@gmail.com \
--cc=delilahwu@linux.microsoft.com \
--cc=delilahwu@microsoft.com \
--cc=git@vger.kernel.org \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=nils@fahldieck.de \
--cc=ps@pks.im \
--cc=stolee@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.